package com.asm.shiroweb.common.exception;

import com.asm.shiroweb.common.lang.Result;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.ExpiredSessionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

@RestControllerAdvice
public class MyExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(ModularRealmAuthenticator.class);



    /**
     * 处理其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    public Result exceptionHandler( Exception e){

        log.error("未知异常！原因是:",e);
        return Result.fail("服务器内部错误！");
    }

    /**
     * 500 没有权限 异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AuthorizationException.class)
    public Result handleAuthorizationException(AuthorizationException e){
        log.error(e.getMessage(), e);
        return Result.fail(HttpStatus.UNAUTHORIZED.value(),"请联系管理员授权后,登陆操作", null);
    }

    @ExceptionHandler(ShiroException.class)
    public Result shiroHandler(ShiroException e){

        log.debug(e.getMessage());
        return Result.fail(500, " ShiroException 抛出的异常：", null);
    }



    /**
     * 400 Bad Request 是由于明显的客户端错误（例如，格式错误的请求语法，太大的大小，无效的请求消息或欺骗性路由请求），服务器不能或不会处理该请求
     *
     * 在 ajax 请求后台数据时比较常见。产生 HTTP 400 错误的原因有：
     *
     * 1、前端提交数据的字段名称或者是字段类型和后台的实体类不一致，导致无法封装；
     * 2、前端提交的到后台的数据应该是 json 字符串类型，而前端没有将对象转化为字符串类型；
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handler(MethodArgumentNotValidException e) {
        log.debug("实体校验异常：----------------{}", e);
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();

        return Result.fail(objectError.getDefaultMessage());
    }


    /**
     * 运行时异常
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = RuntimeException.class)
    public Result handler(RuntimeException e) {
        log.debug("运行时异常：----------------{}", e);
        return Result.fail(e.getMessage());
    }


    /**
     * 请求方法不支持 异常
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result handler(HttpRequestMethodNotSupportedException e) {
        log.debug("请求方法不支持异常：----------------{}", e);
        return Result.fail(e.getMessage());
    }



}
